/**
 * 
 */
package com.usc.entme;

import static android.opengl.GLES10.GL_CCW;
import static android.opengl.GLES10.GL_COLOR_BUFFER_BIT;
import static android.opengl.GLES10.GL_DEPTH_BUFFER_BIT;
import static android.opengl.GLES10.GL_DEPTH_TEST;
import static android.opengl.GLES10.GL_DITHER;
import static android.opengl.GLES10.GL_FASTEST;
import static android.opengl.GLES10.GL_FLOAT;
import static android.opengl.GLES10.GL_MODELVIEW;
import static android.opengl.GLES10.GL_MODULATE;
import static android.opengl.GLES10.GL_PERSPECTIVE_CORRECTION_HINT;
import static android.opengl.GLES10.GL_PROJECTION;
import static android.opengl.GLES10.GL_REPEAT;
import static android.opengl.GLES10.GL_SMOOTH;
import static android.opengl.GLES10.GL_TEXTURE_2D;
import static android.opengl.GLES10.GL_TEXTURE_COORD_ARRAY;
import static android.opengl.GLES10.GL_TEXTURE_ENV;
import static android.opengl.GLES10.GL_TEXTURE_ENV_MODE;
import static android.opengl.GLES10.GL_TEXTURE_WRAP_S;
import static android.opengl.GLES10.GL_TEXTURE_WRAP_T;
import static android.opengl.GLES10.GL_TRIANGLE_STRIP;
import static android.opengl.GLES10.GL_UNSIGNED_SHORT;
import static android.opengl.GLES10.GL_VERTEX_ARRAY;
import static android.opengl.GLES10.glActiveTexture;
import static android.opengl.GLES10.glBindTexture;
import static android.opengl.GLES10.glClear;
import static android.opengl.GLES10.glDisable;
import static android.opengl.GLES10.glDrawElements;
import static android.opengl.GLES10.glEnable;
import static android.opengl.GLES10.glEnableClientState;
import static android.opengl.GLES10.glFrontFace;
import static android.opengl.GLES10.glFrustumf;
import static android.opengl.GLES10.glHint;
import static android.opengl.GLES10.glLoadIdentity;
import static android.opengl.GLES10.glMatrixMode;
import static android.opengl.GLES10.glShadeModel;
import static android.opengl.GLES10.glTexCoordPointer;
import static android.opengl.GLES10.glTexEnvx;
import static android.opengl.GLES10.glTexParameterx;
import static android.opengl.GLES10.glVertexPointer;
import static android.opengl.GLES10.glViewport;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.ArrayList;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import com.usc.entme.News3DActivity.TouchSurfaceView;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.os.SystemClock;
import android.speech.RecognizerIntent;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout.LayoutParams;
import android.widget.Toast;

/**
 * @author pranav
 *
 */
public class Movie3DActivity extends Activity{

	private TouchSurfaceView mGLSurfaceView;
	private ResultRenderer movieRenderer;
	public static Context Context;
	private static final int REQUEST_CODE = 1234;

	public static String TAG ="3D";
	
	public ArrayList<String> movieLinks = new ArrayList<String>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Create our Preview view and set it as the content of our
		// Activity

		Context = this;

		mGLSurfaceView = new TouchSurfaceView(this);		
		setContentView(mGLSurfaceView);
		mGLSurfaceView.requestFocus();
		mGLSurfaceView.setFocusableInTouchMode(true);	
		
		ImageButton toggle2d = new ImageButton(this);  
		  Bitmap image = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.icon2d);  
		  toggle2d.setImageBitmap(image);  
		  toggle2d.setBackgroundColor(Color.BLACK);
		  toggle2d.setMinimumWidth(image.getWidth());  
		  toggle2d.setMinimumHeight(image.getHeight());		
		this.addContentView(toggle2d,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
		
		toggle2d.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	
            	String className = this.getClass().getName();
            	
            	Intent intentActivity;
            	if(className.contains("3D")){
            		// This portion of the code would redirect to the related 2DActivity upon clicking the 2D Mode
    				if(getLocalClassName().contains("News")){
    				intentActivity = new Intent(getBaseContext(),EntmeActivity.class);	
    				intentActivity.putExtra("tabHostIndex", 0);
    			    startActivity(intentActivity);
    				} else if(className.contains("Movie")){
    					intentActivity = new Intent(getBaseContext(),EntmeActivity.class);		
    					intentActivity.putExtra("tabHostIndex", 1);
    					startActivity(intentActivity);
    				} else if(className.contains("Sports")){
    					intentActivity = new Intent(getBaseContext(),EntmeActivity.class);	
    					intentActivity.putExtra("tabHostIndex", 2);
    					startActivity(intentActivity);
    				}			    
    			}else{
    				
    				if(className.equalsIgnoreCase("News")){
    					intentActivity = new Intent(getBaseContext(),News3DActivity.class);			
    				    startActivity(intentActivity);
    					} else if(className.equalsIgnoreCase("Movie")){
    						intentActivity = new Intent(getBaseContext(),Movie3DActivity.class);			
    						startActivity(intentActivity);
    					} else if(className.equalsIgnoreCase("Sports")){
    						intentActivity = new Intent(getBaseContext(),Sports3DActivity.class);			
    						startActivity(intentActivity);
    					}	
    			}
            	
            }
        });
		
		movieLinks.add("http://m.imdb.com/title/tt1324999");
		movieLinks.add("http://m.imdb.com/title/tt1253864");
		movieLinks.add("http://m.imdb.com/title/tt1402488");
		movieLinks.add("http://m.imdb.com/title/tt0448694");
		movieLinks.add("http://m.imdb.com/title/tt1204342");
		movieLinks.add("http://m.imdb.com/title/tt1655420");
		movieLinks.add("http://m.imdb.com/title/tt0970179");
		movieLinks.add("http://m.imdb.com/title/tt1571222");
		movieLinks.add("http://m.imdb.com/title/tt1655442");
		movieLinks.add("http://m.imdb.com/title/tt1430607");
	}

	@Override
	protected void onResume() {
		// Ideally a game should implement onResume() and onPause()
		// to take appropriate action when the activity looses focus
		super.onResume();
		mGLSurfaceView.start();
		mGLSurfaceView.onResume();
	}

	@Override
	protected void onPause() {
		// Ideally a game should implement onResume() and onPause()
		// to take appropriate action when the activity looses focus
		super.onPause();
		mGLSurfaceView.stop();
		mGLSurfaceView.onPause();
	}

	class TouchSurfaceView extends GLSurfaceView implements SensorEventListener {

		private SensorManager mSensorManager;		
		private Sensor mAccelerometer;	
		private float mPreviousX;
		private float mPreviousY;	
		
		private int mActionMoveEventCounter = 0;
		private Boolean swipeAction = false;
		private final float FILTERING_FACTOR = .3f;

		public TouchSurfaceView(Context context) {
			super(context);

			movieRenderer = new ResultRenderer(context, getLocalClassName());
			setRenderer(movieRenderer);
			//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
			mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
			mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);	

		}

		public void start() {

			mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_UI);

		}

		public void stop() {

			mSensorManager.unregisterListener(this);
		}

		@Override
		public void onSensorChanged(SensorEvent event) {

			if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
				return;

			//Log.d(TAG, "Accelerometer Event x = " + event.values[0] + " y = " + event.values[1] + " z = " + event.values[2]);

			Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
			if( display.getRotation() ==  Surface.ROTATION_0 || display.getRotation() ==  Surface.ROTATION_180 ){
				
				//Log.d(TAG, "Portrait Mode Detected");
				movieRenderer.xEyeLocation = (float) (-event.values[0] * FILTERING_FACTOR + movieRenderer.xEyeLocation * (1.0 - FILTERING_FACTOR));
				movieRenderer.yEyeLocation = (float) (-event.values[1] * FILTERING_FACTOR + movieRenderer.yEyeLocation * (1.0 - FILTERING_FACTOR));
			}else if(display.getRotation() ==  Surface.ROTATION_90 || display.getRotation() ==  Surface.ROTATION_270){
				//Log.d(TAG, "Landscape Mode Detected");
				movieRenderer.xEyeLocation = (float) (-event.values[1] * FILTERING_FACTOR + movieRenderer.xEyeLocation * (1.0 - FILTERING_FACTOR));
				movieRenderer.yEyeLocation = (float) (-event.values[0] * FILTERING_FACTOR + movieRenderer.yEyeLocation * (1.0 - FILTERING_FACTOR));				
			}

			/*
			 * 
			 * Seems some issue with these values
			 * 
			newsRenderer.xEyeLocation = (float) (event.values[0] * FILTERING_FACTOR + newsRenderer.xEyeLocation * (1.0 - FILTERING_FACTOR));
			newsRenderer.yEyeLocation = (float) (event.values[1] * FILTERING_FACTOR + newsRenderer.yEyeLocation * (1.0 - FILTERING_FACTOR));
			 */

			movieRenderer.zEyeLocation = (float) (event.values[2] * FILTERING_FACTOR + movieRenderer.zEyeLocation * (1.0 - FILTERING_FACTOR));

			if(movieRenderer.xEyeLocation > 2.0f)
			{
				movieRenderer.xEyeLocation = 2.0f;
			} else if(movieRenderer.xEyeLocation < -2.0f )
			{
				movieRenderer.xEyeLocation = -2.0f;
			}

			if(movieRenderer.yEyeLocation > 2.0f)
			{
				movieRenderer.yEyeLocation = 2.0f;
			}else if(movieRenderer.yEyeLocation < -2.0f )
			{
				movieRenderer.yEyeLocation = -2.0f;
			}

			if(movieRenderer.zEyeLocation > 2.0f)
			{
				movieRenderer.zEyeLocation = 2.0f;
			}else if(movieRenderer.zEyeLocation < -2.0f )
			{
				movieRenderer.zEyeLocation = -2.0f;
			}

		}

		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {
		}


		@Override
		public boolean onTouchEvent(MotionEvent event) { 

			float x = event.getX();
			float y = event.getY();			

			Log.d(TAG ,"MotionEvent X = " + x +" Y = "+y);
			Log.d(TAG, "xPrevious = "+mPreviousX+" yPrevious = "+mPreviousY);


			switch (event.getAction()) {			
			
			case MotionEvent.ACTION_UP:
				Log.d(TAG,"Action UP Detected");	
				
				if(!swipeAction){					
					Log.d(TAG, "It is not a Swipe Action");
					swipeAction = false;
					mActionMoveEventCounter = 0;
					
					int elementIndex = (int)( movieRenderer.zTransition / 4 ) ;
					elementIndex = Math.abs(elementIndex);
					if(elementIndex > movieLinks.size()){
						elementIndex = 0;
					}
					startWebLayoutActivity(movieLinks.get( elementIndex ));
				}		
				
				swipeAction = false;
				mActionMoveEventCounter = 0;
				
				if( y < mPreviousY){	
					
						movieRenderer.zTransition += 4.0 ;			
						
					Log.d(TAG, "zTransition += " + movieRenderer.zTransition);
				}
				else{	
					
						movieRenderer.zTransition -= 4.0 ;					
					Log.d(TAG, "zTransition -= " + movieRenderer.zTransition);
				}
				mGLSurfaceView.requestRender();
				break;
			case MotionEvent.ACTION_MOVE:
				Log.d(TAG,"Action Move Detected");
				mActionMoveEventCounter ++;
				
				//mActionMoveEventCounter > 2 would represent that it is a swipe movement on the screen
				//mActionMoveEventCounter < 2 would mean that it is a click event on the screen.
				if(mActionMoveEventCounter > 12){					
					// Re-intialize to zero					
					swipeAction = true;								
				}			
				
				mGLSurfaceView.requestRender();
				break;
			case MotionEvent.ACTION_DOWN:
				Log.d(TAG,"Action Down Detected");
				mPreviousX = x;
				mPreviousY = y;	        	
				mGLSurfaceView.requestRender();
				break;        	   

			}
			return true;

		}
		

	}
	
	
	public void startWebLayoutActivity(String displayUrl) {
		
		Log.d(TAG, "Inside Start Weblayout Activity");
		
		Intent i = new Intent(Movie3DActivity.this,Url.class );
		Bundle b = new Bundle();
        b.putString("passed", displayUrl);
        i.putExtras(b);
        startActivity(i);		
	}
	
	
	
	private void startVoiceRecognitionActivity()
	{
		Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
		intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
				RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
		intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Voice recognition Demo...");
		startActivityForResult(intent, REQUEST_CODE);
	}

	/**
	 * Handle the results from the voice recognition activity.
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		if (requestCode == REQUEST_CODE && resultCode == RESULT_OK)
		{
			// Populate the wordsList with the String values the recognition engine thought it heard
			ArrayList<String> matches = data.getStringArrayListExtra(
					RecognizerIntent.EXTRA_RESULTS);
			//      wordsList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
			//            matches));

			if(matches.isEmpty())
			{
				Toast.makeText(Context, "No Match found", 2);
			}
			else
			{
				Boolean flag = false;
				for(int i=0;i<matches.size();i++)
				{
					if(matches.get(i).equalsIgnoreCase("news"))
					{
							Log.d(TAG, "News detected int Voice Recognition");
							Intent intent = new Intent(Context,News3DActivity.class);
							intent.putExtra("tabHostIndex", 0);
							startActivity(intent);
							flag =true;
							break;
					}
					if(matches.get(i).equalsIgnoreCase("movies"))
					{
						Intent intent = new Intent(Context,Movie3DActivity.class);
						intent.putExtra("tabHostIndex", 1);
						startActivity(intent);
						flag =true;
						break;
					}
					if(matches.get(i).equalsIgnoreCase("sports"))
					{
						Intent intent = new Intent(Context,Sports3DActivity.class);
						intent.putExtra("tabHostIndex", 2);
						startActivity(intent);
						flag =true;
						break;
					}
					

				}
				if(!flag)
				{
					
					Toast.makeText(Context, "No Match found. Try Again!!", Toast.LENGTH_LONG);
					Log.d(TAG, "No match found");
				}

			}

		}
		super.onActivityResult(requestCode, resultCode, data);
	}
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu3d, menu);
		return true;
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		Intent intentActivity;
		// Handle item selection
		switch (item.getItemId()) {		
		
		case R.id.Settings:
			intentActivity = new Intent(getBaseContext(),Preferences.class);
			startActivity(intentActivity);
			return true;
		case R.id.home:
			intentActivity = new Intent(getBaseContext(),EntmeGridViewActivity.class);
			startActivity(intentActivity);
			return true;
		case R.id.speak:
			startVoiceRecognitionActivity();
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}


}